package admin

import (
	"baokaobang/conf"
	"baokaobang/datasourse"
	"baokaobang/models"
	"baokaobang/utils"
	"encoding/json"
	"fmt"
	"github.com/360EntSecGroup-Skylar/excelize"
	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/mvc"
	"strings"
)

type College struct {
	Ctx iris.Context
}

type CollegeExcelCreate struct {
	ExcelUrl string `json:"excelUrl"`
}

type CollegeCreate struct {
	Id             string  `json:"id"`
	UniversityId   int64   `json:"universityId"`
	CollegeLevelId int64   `json:"collegeLevelId"`
	Name           string  `json:"name"`
	Code           string  `json:"code"`
	IsMatch        int     `json:"isMatch"`
	IsSingle       int     `json:"isSingle"`
	IsCooperation  int     `json:"isCooperation"`
	IsArt          int     `json:"isArt"`
	RegCodeNum     int     `json:"regCodeNum"`
	Labels         []int64 `json:"labels"`
}

type CollegeListParam struct {
	UniversityId   int64  `json:"universityId"`
	CollegeLevelId int64  `json:"collegeLevelId"`
	IsMatch        int    `json:"isMatch"`
	IsArt          int    `json:"isArt"`
	IsSingle       int    `json:"isSingle"`
	IsCooperation  int    `json:"isCooperation"`
	Name           string `json:"name"`
	PerPage        int    `json:"perPage"`
	CurPage        int    `json:"curPage"`
}

type CollegeObj struct {
	models.College      `xorm:"extends"`
	models.CollegeLevel `xorm:"extends"`
}

func (c *College) OptionsAll() mvc.Response {
	return mvc.Response{
		Code: 204,
	}
}

func (c *College) PostAll() interface{} {
	db, err := datasourse.NewMasterOrm()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
	}

	collegeList := make([]models.College, 0)
	err = db.Find(&collegeList)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法获取所有院校列表：%s", err.Error()), "")
	}

	return utils.CommonRes(20000, "成功获取所有院校列表", collegeList)
}

func (c *College) OptionsExcel() mvc.Response {
	return mvc.Response{
		Code: 204,
	}
}

func (c *College) PostExcel() interface{} {
	collegeExcelCreate := CollegeExcelCreate{}
	content, err := c.Ctx.GetBody()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("接受请求参数出错:%s", err.Error()), "")
	}
	err = json.Unmarshal(content, &collegeExcelCreate)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("参数解析出错:%s", err.Error()), "")
	}

	if len(collegeExcelCreate.ExcelUrl) <= 0 {
		return utils.CommonRes(1000, "请上传excel文件", "")
	}

	db, err := datasourse.NewMasterOrm()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
	}

	filePath := fmt.Sprintf("%s%s", conf.UploadPrefix.Backend, collegeExcelCreate.ExcelUrl)
	f, err := excelize.OpenFile(filePath)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("上传的文件无法打开:%s", err.Error()), "")
	}

	sheetList := f.GetSheetMap()
	for _, sheet := range sheetList {
		rows := f.GetRows(sheet)
		for i, row := range rows {
			if i == 0 {
				continue
			}
			ok, err := db.Table(new(models.College)).Where("`code` = ?", row[0]).Exist()
			if err != nil {
				return utils.CommonRes(1000, fmt.Sprintf("根据院校代码查询查询院校出错：%s", err.Error()), "")
			}
			if ok {
				continue
			}
			college := new(models.College)
			college.Code = strings.TrimSpace(row[0])
			college.Name = strings.TrimSpace(row[1])
			_, err = db.InsertOne(college)
			if err != nil {
				return utils.CommonRes(1000, fmt.Sprintf("院校代码%s插入出错：%s", row[0], err.Error()), "")
			}
		}
	}

	return utils.CommonRes(20000, "院校导入成功", "")
}

func (c *College) OptionsCreate() mvc.Response {
	return mvc.Response{
		Code: 204,
	}
}

func (c *College) PostCreate() interface{} {
	collegeCreate := CollegeCreate{}
	content, err := c.Ctx.GetBody()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("接收请求的参数出错：%s", err.Error()), "")
	}
	err = json.Unmarshal(content, &collegeCreate)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("解析请求的参数出错：%s", err.Error()), "")
	}

	if collegeCreate.UniversityId <= 0 {
		return utils.CommonRes(1000, "请选择所属大学", "")
	}
	if len(collegeCreate.Name) <= 0 {
		return utils.CommonRes(1000, "请输入院校名称", "")
	}
	if len(collegeCreate.Code) <= 0 {
		return utils.CommonRes(1000, "请输入院校招生代码", "")
	}

	db, err := datasourse.NewMasterOrm()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
	}

	sess := db.NewSession()
	defer sess.Close()
	err = sess.Begin()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("事务开启失败：%s", err.Error()), "")
	}

	regCode := utils.GenRandCode(4)
	ok, err := sess.Table(new(models.College)).Where("`reg_code` = ?", regCode).Exist()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
	}
	for ok {
		regCode := utils.GenRandCode(4)
		ok, _ = sess.Table(new(models.College)).Where("`reg_code` = ?", regCode).Exist()
	}

	college := new(models.College)
	college.Name = collegeCreate.Name
	college.Code = collegeCreate.Code
	college.UniversityId = collegeCreate.UniversityId
	college.CollegeLevelId = collegeCreate.CollegeLevelId
	college.IsMatch = collegeCreate.IsMatch
	college.IsCooperation = collegeCreate.IsCooperation
	college.IsSingle = collegeCreate.IsSingle
	college.IsArt = collegeCreate.IsArt
	college.RegCode = regCode
	college.RegCodeNum = collegeCreate.RegCodeNum
	_, err = sess.InsertOne(college)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("操作失败：%s", err.Error()), "")
	}

	for _, labelId := range collegeCreate.Labels {
		collegeLabel := new(models.CollegeLabel)
		collegeLabel.CollegeId = college.Id
		collegeLabel.LabelId = labelId
		_, err = sess.InsertOne(collegeLabel)
		if err != nil {
			return utils.CommonRes(1000, fmt.Sprintf("操作失败：%s", err.Error()), "")
		}
	}

	err = sess.Commit()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("操作失败：%s", err.Error()), "")
	}

	return utils.CommonRes(20000, "操作成功", "")
}

func (c *College) OptionsEdit() mvc.Response {
	return mvc.Response{
		Code: 204,
	}
}

func (c *College) PostEdit() interface{} {
	collegeCreate := CollegeCreate{}
	content, err := c.Ctx.GetBody()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("接收请求参数出错:%s", err.Error()), "")
	}
	err = json.Unmarshal(content, &collegeCreate)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("解析请求参数出错:%s", err.Error()), "")
	}

	if collegeCreate.UniversityId <= 0 {
		return utils.CommonRes(1000, "请选择所属大学", "")
	}
	if len(collegeCreate.Name) <= 0 {
		return utils.CommonRes(1000, "请输入院校名称", "")
	}
	if len(collegeCreate.Code) <= 0 {
		return utils.CommonRes(1000, "请输入院校招生代码", "")
	}

	db, err := datasourse.NewMasterOrm()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
	}

	sess := db.NewSession()
	defer sess.Close()
	err = sess.Begin()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("事务开启失败：%s", err.Error()), "")
	}

	updateData := map[string]interface{}{
		"code":             collegeCreate.Code,
		"name":             collegeCreate.Name,
		"university_id":    collegeCreate.UniversityId,
		"college_level_id": collegeCreate.CollegeLevelId,
		"is_match":         collegeCreate.IsMatch,
		"is_cooperation":   collegeCreate.IsCooperation,
		"is_single":        collegeCreate.IsSingle,
		"is_art":           collegeCreate.IsArt,
		"reg_code_num":     collegeCreate.RegCodeNum,
	}
	_, err = sess.Table(new(models.College)).ID(collegeCreate.Id).Update(updateData)
	if err != nil {
		return utils.CommonRes(1000, "操作失败", "")
	}

	collegeLabelList := make([]models.CollegeLabel, 0)
	sess.Where("`college_id` = ?", collegeCreate.Id).Find(&collegeLabelList)
	for _, collegeLabel := range collegeLabelList {
		_, err = sess.ID(collegeLabel.Id).Delete(collegeLabel)
		if err != nil {
			return utils.CommonRes(1000, fmt.Sprintf("院校旧标签删除失败：%s", err.Error()), "")
		}
	}

	for _, labelId := range collegeCreate.Labels {
		collegeLabel := new(models.CollegeLabel)
		collegeLabel.CollegeId = utils.Atoi64(collegeCreate.Id)
		collegeLabel.LabelId = labelId
		_, err = sess.InsertOne(collegeLabel)
		if err != nil {
			return utils.CommonRes(1000, fmt.Sprintf("操作失败：%s", err.Error()), "")
		}
	}

	err = sess.Commit()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("操作失败：%s", err.Error()), "")
	}

	return utils.CommonRes(20000, "操作成功", "")
}

func (c *College) OptionsList() mvc.Response {
	return mvc.Response{
		Code: 204,
	}
}

func (c College) PostList() interface{} {
	collegeListParam := CollegeListParam{}
	content, err := c.Ctx.GetBody()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("接收请求参数出错：%s", err.Error()), "")
	}
	err = json.Unmarshal(content, &collegeListParam)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("解析请求参数出错：%s", err.Error()), "")
	}

	db, err := datasourse.NewMasterOrm()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
	}

	start := (collegeListParam.CurPage - 1) * collegeListParam.PerPage
	collegeList := make([]CollegeObj, 0)
	sess := db.Table(new(models.College)).Alias("c").
		Join("LEFT", []string{"college_level", "cl"}, "c.college_level_id = cl.id").
		Limit(collegeListParam.PerPage, start)
	if collegeListParam.UniversityId > 0 {
		sess = sess.Where("c.university_id = ?", collegeListParam.UniversityId)
	}
	if collegeListParam.CollegeLevelId > 0 {
		sess = sess.Where("c.college_level_id = ?", collegeListParam.CollegeLevelId)
	}
	if collegeListParam.IsMatch > -1 {
		sess = sess.Where("c.is_match = ?", collegeListParam.IsMatch)
	}
	if collegeListParam.IsCooperation > -1 {
		sess = sess.Where("c.is_cooperation = ?", collegeListParam.IsCooperation)
	}
	if collegeListParam.IsSingle > -1 {
		sess = sess.Where("c.is_single = ?", collegeListParam.IsSingle)
	}
	if collegeListParam.IsArt > -1 {
		sess = sess.Where("c.is_art = ?", collegeListParam.IsArt)
	}
	if len(collegeListParam.Name) > 0 {
		sess = sess.Where("c.name like ?", fmt.Sprintf("%%%s%%", collegeListParam.Name))
	}
	err = sess.Find(&collegeList)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法获取院校列表:%s", err.Error()), "")
	}

	sessCount := db.Where("id > ?", 0)
	if collegeListParam.UniversityId > 0 {
		sessCount = sessCount.Where("`university_id` = ?", collegeListParam.UniversityId)
	}
	if collegeListParam.CollegeLevelId > 0 {
		sessCount = sessCount.Where("`college_level_id` = ?", collegeListParam.CollegeLevelId)
	}
	if collegeListParam.IsMatch > -1 {
		sessCount = sessCount.Where("`is_match` = ?", collegeListParam.IsMatch)
	}
	if collegeListParam.IsCooperation > -1 {
		sessCount = sessCount.Where("`is_cooperation` = ?", collegeListParam.IsCooperation)
	}
	if collegeListParam.IsSingle > -1 {
		sessCount = sessCount.Where("`is_single` = ?", collegeListParam.IsSingle)
	}
	if collegeListParam.IsArt > -1 {
		sessCount = sessCount.Where("`is_art` = ?", collegeListParam.IsArt)
	}
	if len(collegeListParam.Name) > 0 {
		sessCount = sessCount.Where("`name` like ?", fmt.Sprintf("%%%s%%", collegeListParam.Name))
	}
	total, err := sessCount.Count(new(models.College))
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法获取院校列表：%s", err.Error()), "")
	}

	for i, college := range collegeList {
		collegeList[i].College.IsMatchShow = models.CollegeIsMatch[college.IsMatch]
		collegeList[i].College.IsCooperationShow = models.CollegeIsCooperation[college.IsCooperation]
		collegeList[i].College.IsSingleShow = models.CollegeIsSingle[college.IsSingle]
		collegeList[i].College.IsArtShow = models.CollegeIsArt[college.IsArt]
		collegeList[i].CollegeLevel.Name = fmt.Sprintf("%d~%d", college.CollegeLevel.High, college.CollegeLevel.Low)
	}

	data := map[string]interface{}{
		"total": total,
		"list":  collegeList,
	}

	return utils.CommonRes(20000, "成功获取学院列表", data)
}

func (c *College) OptionsDetail() mvc.Response {
	return mvc.Response{
		Code: 204,
	}
}

func (c *College) PostDetail() interface{} {
	editParam := utils.EditParam{}
	content, err := c.Ctx.GetBody()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("接收请求参数出错：%s", err.Error()), "")
	}
	err = json.Unmarshal(content, &editParam)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("解析请求参数出错：%s", err.Error()), "")
	}

	if len(editParam.Id) <= 0 {
		return utils.CommonRes(1000, "请提供院校id", "")
	}

	db, err := datasourse.NewMasterOrm()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
	}

	college := new(models.College)
	ok, err := db.ID(editParam.Id).Get(college)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("信息获取失败：%s", err.Error()), "")
	}
	if !ok {
		return utils.CommonRes(1000, "信息获取失败", "")
	}

	collegeLabelList := make([]models.CollegeLabel, 0)
	db.Where("`college_id` = ?", college.Id).Find(&collegeLabelList)
	college.Labels = collegeLabelList

	return utils.CommonRes(20000, "信息获取成功", college)
}

func (c *College) OptionsDel() mvc.Response {
	return mvc.Response{
		Code: 204,
	}
}

func (c *College) PostDel() interface{} {
	delParam := utils.DelParam{}
	content, err := c.Ctx.GetBody()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("接收请求参数出错:%s", err.Error()), "")
	}
	err = json.Unmarshal(content, &delParam)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("解析请求参数出错:%s", err.Error()), "")
	}

	if len(delParam.Ids) <= 0 {
		return utils.CommonRes(1000, "请提供要删除项的id", "")
	}

	db, err := datasourse.NewMasterOrm()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库:%s", err.Error()), "")
	}

	ids := strings.Split(delParam.Ids, ",")
	for _, id := range ids {
		college := new(models.College)
		db.ID(id).Get(college)
		db.ID(id).Delete(college)
	}

	return utils.CommonRes(20000, "操作成功", "")
}
